package com.example.validdemo.util;

import lombok.SneakyThrows;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * @author Bx_Hu
 */
public class ValidateUtil {

    public static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

    /**
     * 校验参数返回错误未通过的错误集合
     *
     * @param t 泛型对象
     * @return java.util.List<java.lang.String>
     * @author Bx_Hu
     * @date 18:51 2021-7-18
     **/
    public static <T> List<String> validateMessages(T t) {
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);
        return constraintViolations.stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.toList());
    }

    /**
     * 校验参数,@notnull @size
     *
     * @param object 需要校验的对象
     * @author Bx_Hu
     * @date 18:51 2021-7-18
     */
    @SneakyThrows
    public static void validate(Object object) {
        SpringValidatorAdapter springValidatorAdapter = new SpringValidatorAdapter(factory.getValidator());
        BindingResult errors = new BeanPropertyBindingResult(object, object.getClass()
                .getName());
        springValidatorAdapter.validate(object, errors);
        if (errors.hasErrors()) {
            throw new BindException(errors);
        }
    }

    /**
     * 校验参数,@notnull @size
     *
     * @param object          需要校验的对象
     * @param validationHints 校验器
     * @throws BindException 校验不通过抛出异常
     * @author Bx_Hu
     * @date 18:51 2021-7-18
     */
    public static void validate(Object object, Object... validationHints) throws BindException {
        SpringValidatorAdapter springValidatorAdapter = new SpringValidatorAdapter(factory.getValidator());
        BindingResult errors = new BeanPropertyBindingResult(object, object.getClass()
                .getName());
        springValidatorAdapter.validate(object, errors, validationHints);
        if (errors.hasErrors()) {
            throw new BindException(errors);
        }
    }

}
